package com.expense.app.admin.services.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.expense.app.admin.common.BaseService;
import com.expense.app.admin.model.dto.login.LoginDTO;
import com.expense.app.admin.model.dto.login.UserInfoDTO;
import com.expense.app.admin.model.params.login.ChangePasswordParam;
import com.expense.app.admin.model.params.login.LoginDetailParam;
import com.expense.app.admin.model.params.login.UserInfoParam;
import com.expense.app.admin.services.LoginServ;
import com.expense.common.constant.enums.ResultCode;
import com.expense.common.dao.auth.AdminMenuDao;
import com.expense.common.dao.auth.AdminUserDao;
import com.expense.common.entity.router.MenuRouter;
import com.expense.common.entity.router.MetaRouter;
import com.expense.common.exception.PlatformException;
import com.expense.common.model.auth.AdminMenu;
import com.expense.common.model.auth.AdminUser;
import com.expense.common.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;


@Service
public class LoginServImpl extends BaseService implements LoginServ {

    @Autowired
    AdminUserDao adminUserDao;

    @Autowired
    AdminMenuDao adminMenuDao;


    @Override
    public LoginDTO findOne(LoginDetailParam param) {
        if(param ==null)return  null;
        if(param.getUsername() == null || param.getPassword() == null) return  null;
        String password = SecureUtil.md5(param.getPassword());
        AdminUser adminUser = adminUserDao.findByUserNameAndPasswordAndDeleted(param.getUsername(),password);
        if(adminUser == null) throw new PlatformException("用户名或密码错误！");
        String token = JwtUtil.createJWT(adminUser.getId());
        return new LoginDTO(token);
    }

    @Override
    @Cacheable(cacheNames = "userInfo",value = "userInfo",key = "#param.token")
    public UserInfoDTO getUserInfo(UserInfoParam param) {
        String token = param.getToken();
        Claims claims = JwtUtil.parseJwtToken(token);
        Long userId = 0l;
        if(claims != null) userId = Convert.toLong(claims.get("userId"),0l);
        if(userId <= 0) throw new PlatformException(ResultCode.NO_LOGIN.getCode(),"验证用户信息失败");

        AdminUser adminUser = adminUserDao.findByIdAndDeleted(userId);
        if(adminUser == null) throw new PlatformException(ResultCode.NO_LOGIN.getCode(),"用户不存在或已注销");

        //拼装前端需要的异步路由
        List<AdminMenu> menuList = adminUserDao.findMenusByUser(adminUser.getId());
        List<AdminMenu> adminMenuList = AdminMenu.generateListTree(menuList,"0");
        List<MenuRouter> routerList = filterRouter(adminMenuList);

        return new UserInfoDTO(adminUser,routerList);
    }

    public List<MenuRouter> filterRouter(List<AdminMenu> menus) {
        List<MenuRouter> menuRouterList = new ArrayList<>();
        if(menus == null || menus.size() == 0) return menuRouterList;
        menus.parallelStream().forEach(menu -> {
            MenuRouter menuRouter = new MenuRouter();
            menuRouter.setPath(menu.getPath());
            menuRouter.setComponent(menu.getComponent());
            menuRouter.setRoles("admin");
            menuRouter.setName(menu.getName());
//            if(StrUtil.isNotBlank(menu.getName()))menuRouter.setName(menu.getPageName());
            if(StrUtil.isNotBlank(menu.getRedirect()))menuRouter.setRedirect(menu.getRedirect());
            if(Convert.toBool(menu.getIsHidden(),false))menuRouter.setHidden(menu.getIsHidden());
            MetaRouter metaRouter = new MetaRouter();
            metaRouter.setTitle(menu.getTitle());
            metaRouter.setIcon(menu.getIconCls());
            if(Convert.toBool(menu.getNoCache(),false))metaRouter.setNoCache(menu.getNoCache());

            menuRouter.setMeta(metaRouter);
            if(menu.getChildren() != null && menu.getChildren().size() > 0) {
                menuRouter.setChildren(filterRouter(menu.getChildren()));
            }
            menuRouter.setSort(menu.getShowOrder());
            menuRouterList.add(menuRouter);
        });
        menuRouterList.sort(new Comparator<MenuRouter>() {
            @Override
            public int compare(MenuRouter a, MenuRouter b) {
                return a.getSort().compareTo(b.getSort());
            }
        });
        return menuRouterList;
    }

    @Override
    public void changePassword(ChangePasswordParam param) {
        AdminUser loginUser = getCurrentUser();
        String md5Pass = SecureUtil.md5(param.getPassword());
        if(!md5Pass.equals(loginUser.getPassword())) throw new PlatformException("登录密码错误");
        String md5NewPass = SecureUtil.md5(param.getNewPassword());
        setBaseInfo(loginUser);
        loginUser.setPassword(md5NewPass);
        adminUserDao.saveOne(loginUser);
    }
}
